package com.ssm.service.impl;

import com.github.pagehelper.PageHelper;
import com.ssm.dao.IFileDao;
import com.ssm.domain.SysFile;
import com.ssm.service.IFileService;

import com.ssm.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;

/**
 * 文件业务接口实现
 */
@Service
public class FileServiceImpl implements IFileService {

    @Autowired
    private IFileDao fileDao;

    @Autowired
    private HttpSession session;

    @Autowired
    private HttpServletRequest request;

    @Override
    public List<SysFile> findAll(Integer page,Integer size) throws Exception {
        PageHelper.startPage(page,size);
        return fileDao.findAll();
    }

    @Override
    public void deleteFile(String fileId) throws Exception {
        fileDao.deleteFileformFolder(fileId);
        fileDao.deleteFileByFileId(fileId);
    }

    @Override
    public void save(MultipartFile[] files) throws IOException {
        String realPath = session.getServletContext().getRealPath("/file/");
        System.out.println("上传路径 "+ realPath);

        //从上下文中获取当前的用户
        SecurityContext context = SecurityContextHolder.getContext();
        User user = (User) context.getAuthentication().getPrincipal();
        String username = user.getUsername();
        System.out.println("上传用户 "+ username);
        //将文件保存到物理磁盘
        //将相关数据保存到数据库
        for (MultipartFile file: files) {
            String filename = file.getOriginalFilename();

            int m = (int) (file.getSize() / 1024.0 / 1024.0 * 1000);
            //文件大小
            String filesize = (m/1000.0) + "M";
            //文件类型
            String type = filename.substring(filename.lastIndexOf(".") + 1);
            //文件保存地址时的文件名
            String pathName = DateUtils.date2String(new Date(),"yyyyMMddHHmmss");
            String newName = pathName + "." + type;

            String filepath = realPath + java.io.File.separator + newName;
            SysFile sysFile = new SysFile();
            sysFile.setFilename(filename);
            sysFile.setFilesize(filesize);
            sysFile.setFiletype(type);
            sysFile.setFilepath(filepath);
            sysFile.setUploadtime(new Date());
            sysFile.setUsername(username);
            fileDao.fileInsert(sysFile);
            //将文件保存到物理磁盘
            file.transferTo(new File(realPath,newName));
        }
    }

    @Override
    public SysFile findById(String fileId) throws Exception {
        return fileDao.findById(fileId);
    }

    @Override
    public void downloadFile(String fileId) throws Exception {
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();

        SysFile file = fileDao.selectOne(fileId);
        //获取文件的物理路径
        String newName = DateUtils.date2String(file.getUploadtime(),"yyyyMMddHHmmss");
        System.out.println("文件名：" + newName);
        String path = request.getServletContext().getRealPath("/file/");
        String filepath = path + newName + "." + file.getFiletype();

        System.out.println("下载路径：" + filepath);
        //使用输入流读取文件
        byte[] b = new byte[1024];
        int len = -1;

        //文件下载时，由于浏览器默认支持一些文件可以解析
        //要在响应头中设置浏览器处理数据的方式
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        //中文名称乱码解决，需要将名称进行编码
        String name = URLEncoder.encode(file.getFilename(),"UTF-8");
        //在响应头设置文件名称
        response.addHeader("Content-Disposition","attachment; filename=" + name);
        //未分类的二进制数据
        response.setContentType("application/octet-stream");
        //文件大小
        response.setHeader("Content-Length", String.valueOf(new File(filepath).length()));
        //使用输出流输出文件
        BufferedOutputStream os = new BufferedOutputStream(response.getOutputStream());

        FileInputStream fis = new FileInputStream(new File(filepath));
        while ((len = fis.read(b)) != -1) {
            os.write(b,0,len);
            os.flush();
        }
        os.close();
        fis.close();
    }

    /**
     * 模糊查询
     * @param page
     * @param size
     * @param keyWord
     * @return
     */
    @Override
    public List<SysFile> selectFile(Integer page, Integer size, String keyWord) {
        PageHelper.startPage(page,size);
        return fileDao.selectFiles(keyWord);
    }

}
